home *** CD-ROM | disk | FTP | other *** search
/ Reverse Code Engineering RCE CD +sandman 2000 / ReverseCodeEngineeringRceCdsandman2000.iso / RCE / Tools / TASM V5 / CPUID.PAK / CPUID.ASM next >
Encoding:
Assembly Source File  |  1996-02-21  |  9.2 KB  |  275 lines

  1. ;       cpuid.asm 
  2. ;
  3. ;       CPU detector program.
  4. ;
  5. ;       Copyright (c) 1993 by Borland International, Inc.
  6. ;
  7. ;       Build with the provided makefile: make -B
  8.  
  9.  
  10.         TITLE CPUID
  11.         JUMPS
  12.         .model small
  13.         .stack 100h
  14.         .data
  15. saved_cpuid     dd      ?
  16. vendor_id       db      12 dup (?)
  17. cpu_type        db      ?
  18. themodel        db      ?
  19. stepping        db      ?
  20. id_flag         db      0
  21. intel_proc      db      0
  22. id_msg          db      "This system has a$"
  23. c8086           db      "n 8086/8088 microprocessor$"
  24. c286            db      "n Intel 286 microprocessor$"
  25. c386            db      "n Intel386 (TM) microprocessor$"
  26. c486            db      "n Intel486 (TM) DX microprocessor$"
  27. Pentium         db      " Pentium(TM) microprocessor", 13, 10, "$"
  28. intel           db      "This system contains a Genuine Intel Processor", 13, 10, "$"
  29. modelmsg        db      "Model:         $"
  30. steppingmsg     db      "Stepping:      $"
  31. familymsg       db      "Processor Family: $"
  32. period          db      ".",13,10,"$"
  33. dataCR          db      ?,13,10,"$"
  34. intel_id        db      "GenuineIntel"
  35.  
  36. .code
  37. .8086            ; This part of the program must run on an 8086
  38. start:  mov     ax,@data
  39.         mov     ds, ax                  ;set segment register
  40.         mov     es, ax                  ;set segment register
  41.         and     sp, not 3               ;align stack to avoid AC fault
  42.         call    get_cpuid
  43.         call    print
  44.         mov     ax,4c00h                ; terminate program
  45.         int     21h
  46.  
  47. get_cpuid        proc
  48.  
  49. ;       8086 CPU check
  50. ;       Bits 12-15 are always set on the 8086 processor
  51. ;
  52. check_8086:
  53.         pushf                           ;save FLAGS
  54.         pop     bx                      ;store FLAGS in BX
  55.         mov     ax, 0fffh               ;clear bits 12-15
  56.         and     ax, bx                  ;  in FLAGS
  57.         push    ax                      ;store new FLAGS calue on stack
  58.         popf                            ;replace current FLAGS value
  59.         pushf                           ;set new flags
  60.         pop     ax                      ;store new flags in AX
  61.         and     ax, 0f000h              ;if bits 12-15 are set, then CPU
  62.         cmp     ax, 0f000h              ;  is an 8086/8088
  63.         mov     cpu_type, 0             ; save the CPU type
  64.         je      end_get_cpuid
  65.  
  66.  
  67. ;
  68. ;       Intel 286 CPU check
  69. ;       Bits 12-15 are always clear on the Intel processor.
  70. ;
  71. check_80286:
  72. .286
  73.         or      bx, 0f000h              ;try to set bits 12-15
  74.         push    bx
  75.         popf
  76.         pushf
  77.         pop     ax
  78.         and     ax, 0f000h              ; if bits 12-15 are cleared,
  79.                                         ;       CPU=Intel 286
  80.         mov     cpu_type, 2             ; turn on Intel 286 Cpu flag
  81.         jz      end_get_cpuid           ; if CPU is intel 286, check
  82.                                         ; for Intel 287 math coprocessor
  83.  
  84. ;       Intel386 CPU check
  85. ;       The AC bit (bit 18), is a new bit introduced in the EFLAGS
  86. ;       register on the Intel486 DX CPU to generate alignment faults.
  87. ;       This bit can not be set on the Intel386 CPU.
  88. ;
  89. check_intel386:
  90. .386
  91.         pushfd
  92.         pop     eax                     ;get original EFLAGS
  93.         mov     ecx,eax                 ; save original EFLAGS
  94.         xor     eax,40000h              ;flip AC bit in EFLAGS
  95.         push    eax                     ; save for EFLAGS
  96.         popfd                           ; copy to EFLAGS
  97.         pushfd                          ; push EFLAGS
  98.         pop     eax                     ; get new EFLAGS value
  99.         xor     eax,ecx                 ; can't toggle AC bit, CPU=Intel386
  100.         mov     cpu_type, 3             ; turn on Intel386 CPU flag
  101.         je      end_get_cpuid           ; if CPU is Intel386, now check
  102.                                         ; for an Intel 287 or Intel387 MCP
  103.  
  104. ;     Intel486 DX CPU, Intel 487 SX MCP, and Intel486 SX CPU checking
  105. ;
  106. ;     Checking for the ability to set/clear the ID flag (bit 21) in EFLAGS
  107. ;     which diferentiates between Pentium (or greater) and the Intel486.
  108. ;     If the ID flag is set then the CPUID instruction can be used to
  109. ;     determine the final version of the chip, else it's a 486
  110. ;
  111. ;
  112. check_Intel486:
  113. .486
  114.         mov     cpu_type, 4             ;turn on Intel486 CPU flag
  115.         pushfd                          ;push original EFLAGS
  116.         pop     eax                     ; get original EFLAGS in eax
  117.         mov     ecx,eax                 ;save original EFLAGS in ecx
  118.         or      eax,200000h             ; flip ID bit in EFLAGS
  119.         push    eax                     ;save for EFLAGS
  120.         popfd                           ;copy to EFLAGS
  121.         pushfd                          ;push EFLAGS
  122.         pop     eax                     ;get new EFLAGS value
  123.         xor     eax,ecx
  124.         je      end_get_cpuid           ;if ID bit cannot be changed,
  125.                                         ;CPU=Intel486 without CPUID
  126.                                         ;instruction functionality
  127.  
  128. ;       Otherwise, execute CPUID instruction to determine vendor,
  129. ;       family, model and stepping.
  130.  
  131. check_vendor:
  132. .586
  133.         mov     id_flag, 1              ; set flag for indicating use of
  134.                                         ;CPUID inst
  135.         mov     eax, 0                  ;set up for CPUID instruction
  136.         cpuid
  137.         mov     dword ptr vendor_id, ebx; Test for "GenuineIntel" vendor id.
  138.         mov     dword ptr  vendor_id[+4], edx
  139.         mov     dword ptr vendor_id[+8], ecx
  140.         mov     si, offset vendor_id
  141.         mov     di, offset intel_id
  142.         mov     cx, length intel_id
  143. compare:
  144.         repe    cmpsb
  145.         cmp     cx, 0                   ; must be a GenuineIntel if ecx =0
  146.         jne     cpuid_data
  147.  
  148. intel_processor:
  149.         mov     intel_proc, 1
  150.         mov     [intel-1], ' '          ; add a space so the Genuine Intel 
  151.                                         ; message prints out.
  152.  
  153. cpuid_data:
  154.         mov     eax, 1
  155.         cpuid
  156.         mov     saved_cpuid,eax         ;save for future use
  157.         and     eax, 0F00H              ; mask everything but family
  158.         shr     eax, 8
  159.         mov     cpu_type, al            ; set cpu_type with family
  160.  
  161.         mov     eax,saved_cpuid         ;restore data
  162.         mov     stepping, al
  163.         and     stepping, 0FH           ; isolate stepping info
  164.  
  165.         mov     eax, saved_cpuid
  166.         mov     themodel, al
  167.         and     themodel, 0F0H          ; isolate model info
  168.         shr     themodel, 4
  169.  
  170. end_get_cpuid:
  171. .8086
  172.         ret
  173. get_cpuid       endp
  174.  
  175. ;
  176. ;       This procedure prints the appropriate cpuid string
  177. ;       If the CPUID instruction was supported, it prints out
  178. ;       the cpuid info.
  179.  
  180. print   proc
  181.         push    ax
  182.         push    bx
  183.         push    cx
  184.         push    dx
  185.         cmp     id_flag, 1              ; if set to 1, cpu supported CPUID
  186.                                         ; instruction
  187.                                         ; print detailed CPUID information
  188.         je      print_cpuid_data
  189.  
  190.         mov     dx, offset id_msg 
  191.         mov     ah, 9h
  192.         int     21h                     ; print initial message
  193.  
  194. print_86:
  195.         cmp     cpu_type, 0
  196.         jne     print_286
  197.         mov     dx, offset c8086
  198.         mov     ah, 9h
  199.         int     21h
  200.         jmp     end_print
  201.  
  202. print_286:
  203.         cmp     cpu_type, 2
  204.         jne     print_386
  205.         mov     dx, offset c286
  206.         mov     ah, 9h
  207.         int     21h
  208.         jmp     end_print
  209.  
  210.  
  211. print_386:
  212.         cmp     cpu_type, 3
  213.         jne     print_486
  214.         mov     dx, offset c386
  215.         mov     ah, 9h
  216.         int     21h
  217.         jmp     end_print
  218.  
  219.  
  220. print_486:
  221.         mov     dx, offset  c486
  222.         mov     ah, 9h
  223.         int     21h
  224.         jmp     end_print
  225.  
  226. print_cpuid_data:
  227.  
  228.         cmp     cpu_type, 5
  229.         jne     print_cpuid_cont
  230.  
  231.         mov     dx, offset Pentium
  232.         mov     ah, 9
  233.         int     21h
  234.  
  235. print_cpuid_cont:
  236.         mov     dx, offset familymsg    ;print family msg
  237.         mov     ah, 9h
  238.         int     21h
  239.         mov     al, cpu_type
  240.         mov     byte ptr dataCR, al
  241.         add     byte ptr dataCR, 30H    ; convert to ASCII
  242.         mov     dx,  offset dataCR      ; print family info
  243.         mov     ah, 9h
  244.         int     21h
  245.  
  246.         mov     dx, offset steppingmsg  ; print stepping msg
  247.         mov     ah, 9h
  248.         int     21h
  249.         mov     al, stepping
  250.         mov     byte ptr dataCR, al
  251.         add     byte ptr dataCR, 30H    ; convert to ASCII
  252.         mov     dx, offset dataCR       ; print stepping info
  253.         mov     ah, 9h
  254.         int     21h
  255.  
  256.         mov     dx, offset modelmsg     ; print model msg
  257.         mov     ah, 9h
  258.         int     21h
  259.         mov     al, themodel
  260.         mov     byte ptr dataCR, al
  261.         add     byte ptr dataCR, 30H    ; convert to ASCII
  262.         mov     dx, offset dataCR       ; print stepping info
  263.         mov     ah, 9h
  264.         int     21h
  265. end_print:
  266.         pop     dx
  267.         pop     cx
  268.         pop     bx
  269.         pop     ax
  270.         ret
  271. print   endp
  272.  
  273.         end     start
  274.  
  275.